/**
 * Copyright (c) iwindplus Technologies Co., Ltd.2024-2030, All rights reserved.
 */

package com.iwindplus.cloud.i18n.manager;

import cn.hutool.core.text.CharSequenceUtil;
import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import com.iwindplus.boot.domain.constant.CommonConstant.ExceptionConstant;
import com.iwindplus.boot.domain.constant.CommonConstant.SymbolConstant;
import com.iwindplus.cloud.i18n.domain.constant.I18nConstant;
import com.iwindplus.cloud.i18n.domain.property.I18nProperty;
import com.iwindplus.cloud.i18n.support.NacosBundleMessageSource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;

/**
 * 动态路由管理器（先从Nacos读取，读取不到从db读取，同步Nacos）.
 *
 * @author zengdegui
 * @since 2020/4/15
 */
@Slf4j
@Data
@AllArgsConstructor
public class I18nManager implements ApplicationRunner {

    private NacosConfigManager nacosConfigManager;

    private NacosBundleMessageSource messageSource;

    private I18nProperty property;

    /**
     * Nacos监听.
     *
     * @param fileName 文件名
     * @param group    分组
     */
    public void nacosListener(String fileName, String group) {
        ConfigService configService = this.nacosConfigManager.getConfigService();
        try {
            final String dataId = new StringBuilder(fileName).append(I18nConstant.FILE_SUFFIX).toString();
            configService.addListener(dataId, group, new NacosListener(fileName));
        } catch (NacosException ex) {
            log.error("NacosException，message={}", ex.getMessage(), ex);
        }
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        String group = this.property.getGroup();
        final List<String> dataIdList = this.getDataIdList();
        dataIdList.stream().forEach(dataId -> {

            log.info("创建Nacos监听，监听文件名={}", dataId);

            this.nacosListener(dataId, group);
        });
    }

    private List<String> getDataIdList() {
        List<String> dataIdList = new ArrayList<>(10);
        final String baseName = this.property.getBasename();
        String fileName;
        if (CharSequenceUtil.contains(baseName, SymbolConstant.SLASH)) {
            fileName = CharSequenceUtil.subAfter(baseName, SymbolConstant.SLASH, true);
        } else {
            fileName = baseName;
        }
        this.property.getLanguages().stream().forEach(language -> {
            String dataId = new StringBuilder(fileName)
                .append(SymbolConstant.UNDERLINE)
                .append(CharSequenceUtil.subBefore(language, SymbolConstant.HORIZONTAL_LINE, true))
                .append(SymbolConstant.UNDERLINE)
                .append(CharSequenceUtil.subAfter(language, SymbolConstant.HORIZONTAL_LINE, true))
                .toString();
            dataIdList.add(dataId);
        });
        return dataIdList;
    }

    @Data
    @AllArgsConstructor
    private class NacosListener implements Listener {

        /**
         * 文件名
         */
        private String fileName;

        @Override
        public Executor getExecutor() {
            return null;
        }

        @Override
        public void receiveConfigInfo(String configInfo) {
            try {
                messageSource.forceRefresh(fileName, configInfo);
            } catch (Exception e) {
                log.error(ExceptionConstant.EXCEPTION, e);
            }
        }
    }
}
